package org.opens.controller;

import org.opens.entity.Order;
import org.opens.entity.Product;
import org.opens.service.OrderService;
import org.opens.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Objects;
import java.util.Random;

@RestController
@RequestMapping(value = "/api/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private ProductService productService;

    @RequestMapping(value = "/create/{productId}/{num}")
    public Order createOrder(
            @PathVariable(value = "productId") Integer productId,
            @PathVariable(value = "num") Integer num
    ) {
        Product pro = restTemplate.getForObject("http://localhost:8081/api/product/" + productId, Product.class);
        if (pro == null) {
            throw new NullPointerException("所查询商品为null");
        }
        Order order = new Order();
        // 设置用户信息
        order.setUserId(1);
        order.setUsername("test");
        // 设置商品信息
        order.setProId(productId);
        order.setProName(pro.getName());
        order.setNumber(num);
        order.setProPrice(pro.getPrice());

        try {
            order = orderService.save(order);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("保存订单出现错误");
            return null;
        }
        return order;
    }

    @RequestMapping(value = "/create2/{productId}/{num}")
    public Order createOrder2(
            @PathVariable(value = "productId") Integer productId,
            @PathVariable(value = "num") Integer num
    ) {
        List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
        ServiceInstance serviceInstance = instances.get(0);
        String apiUrl = serviceInstance.getHost() + ":" + serviceInstance.getPort();
        Product pro = restTemplate.getForObject("http://" + apiUrl + "/api/product/" + productId, Product.class);
        if (pro == null) {
            throw new NullPointerException("所查询商品为null");
        }
        Order order = new Order();
        // 设置用户信息
        order.setUserId(1);
        order.setUsername("test");
        // 设置商品信息
        order.setProId(productId);
        order.setProName(pro.getName());
        order.setNumber(num);
        order.setProPrice(pro.getPrice());

        try {
            order = orderService.save(order);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("保存订单出现错误");
            return null;
        }
        return order;
    }

    /**
     * 功能:
     * <pre>
     *     自定义实现负载均衡;
     * </pre>
     */
    @RequestMapping(value = "/create3/{productId}/{num}")
    public Order createOrder3(
            @PathVariable(value = "productId") Integer productId,
            @PathVariable(value = "num") Integer num
    ) {
        List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
        // 自定义随机负载均衡
        int serviceIndex = new Random().nextInt(instances.size());
        ServiceInstance serviceInstance = instances.get(serviceIndex);
        String apiUrl = serviceInstance.getHost() + ":" + serviceInstance.getPort();
        Product pro = restTemplate.getForObject("http://" + apiUrl + "/api/product/" + productId, Product.class);
        if (pro == null) {
            throw new NullPointerException("所查询商品为null");
        }
        Order order = new Order();
        // 设置用户信息
        order.setUserId(1);
        order.setUsername("test");
        // 设置商品信息
        order.setProId(productId);
        order.setProName(pro.getName());
        order.setNumber(num);
        order.setProPrice(pro.getPrice());

        try {
            order = orderService.save(order);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("保存订单出现错误");
            return null;
        }
        return order;
    }

    /**
     * 说明:
     * <pre>
     *     1. 基于Ribbon实现负载均衡.
     * </pre>
     *
     */
    @RequestMapping(value = "/create4/{productId}/{num}")
    public Order createOrder4(
            @PathVariable(value = "productId") Integer productId,
            @PathVariable(value = "num") Integer num
    ) {
        // 直接使用nacos中的serviceid替换ip和端口
        Product pro = restTemplate.getForObject("http://service-product/api/product/" + productId, Product.class);
        if (pro == null) {
            throw new NullPointerException("所查询商品为null");
        }
        Order order = new Order();
        // 设置用户信息
        order.setUserId(1);
        order.setUsername("test");
        // 设置商品信息
        order.setProId(productId);
        order.setProName(pro.getName());
        order.setNumber(num);
        order.setProPrice(pro.getPrice());

        try {
            order = orderService.save(order);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("保存订单出现错误");
            return null;
        }
        return order;
    }

    /**
     * 说明:
     * <pre>
     *     1. 基于Feign实现负载均衡.
     * </pre>
     *
     */
    @RequestMapping(value = "/create5/{productId}/{num}")
    public Order createOrder5(
            @PathVariable(value = "productId") Integer productId,
            @PathVariable(value = "num") Integer num
    ) {
        // 使用Feign方式的service接口访问远程接口
        Product pro = productService.findById(productId);
        if (pro == null) {
            throw new NullPointerException("所查询商品为null");
        }
        Order order = new Order();
        // 设置用户信息
        order.setUserId(1);
        order.setUsername("test");
        // 设置商品信息
        order.setProId(productId);
        order.setProName(pro.getName());
        order.setNumber(num);
        order.setProPrice(pro.getPrice());

        try {
            order = orderService.save(order);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("保存订单出现错误");
            return null;
        }
        return order;
    }

}
